﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using MessageCenter;
using System.Net.Sockets;
using IPMsgExpections;
using CommonUtility;
using System.Text;

namespace IPMSG
{
    internal class RemoteUser : SocketChatClient
    {
        //用户名
        private string userName;

        //主机名
        private string hostName;

        //udpclient
        private UdpAnySourceMulticastClient udpListner;

        private IPMsgFileInfo fileToTrans;

        //获取或设置主机名
        internal string HostName
        {
            get { return hostName; }
            set { hostName = value; }
        }

        //获取或设置用户名
        internal string UserName
        {
            get { return userName; }
            set { userName = value; }
        }

        internal UdpAnySourceMulticastClient UdpListner
        {
            get { return this.udpListner; }
            set { this.udpListner = value; }
        }

        //构造方法
        internal RemoteUser(MessageModel receiveMessage, IPEndPoint remoteIpep, UdpAnySourceMulticastClient udpClient)
        {
            this.IpEP = remoteIpep;
            this.userName = receiveMessage.UserName;
            this.hostName = receiveMessage.HostName;
            this.udpListner = udpClient;
        }

        internal override void HandleMessage(byte[] buffer)
        {
            Log.Debug(Gb2312Encoding.GetString(buffer));
            this.HandleMessage(MessageModel.DecodingMessage(buffer));
            base.HandleMessage(buffer);
        }

        //消息处理逻辑
        internal void HandleMessage(object stateInfo)
        {
            MessageModel receiveMessage = stateInfo as MessageModel;
            MessageModel messageToSend = null;

            try
            {
                if (receiveMessage is MessageNoopration)
                {
                }
                //上线通知消息
                else if (receiveMessage is MessageBrEntry)
                {
                    Log.Info(string.Format("{0}({1})上线或者刷新用户列表.", this.hostName, this.IpEP.ToString()));

                    //回复AnsEntry消息
                    messageToSend = new MessageAnsEntry(MyInfo.Instance.UserName, MyInfo.Instance.HostName, MyInfo.Instance.IndexPackage);
                    this.SendMessage(messageToSend);
                }
                //AnsEntry消息
                else if (receiveMessage is MessageAnsEntry)
                {
                    Log.Info(string.Format("{0}({1})在线.", this.hostName, this.IpEP.ToString()));
                }
                //离线通知消息
                else if (receiveMessage is MessageBrExit)
                {
                    Log.Info(string.Format("{0}({1})离线.", this.hostName, this.IpEP.ToString()));

                    //从用户列表中删除当前对象
                    if (IPMsgManager.Instance.RemoteUsers.ContainsKey(this.hostName))
                    {
                        System.Threading.ThreadPool.QueueUserWorkItem(
                            new System.Threading.WaitCallback(this.FireUserExit),
                            this);

                        IPMsgManager.Instance.RemoteUsers.Remove(this.hostName);
                    }
                    else
                    {
                        Log.Warning(string.Format("{0}({1})不在用户列表中，无法删除.", this.hostName, this.IpEP.ToString()));
                    }
                }
                //SendMsg消息
                else if (receiveMessage is MessageSendMsg)
                {
                    Log.Info(string.Format("收到来自{0}({1})的{2}号消息：{3}", this.hostName, this.IpEP.ToString(), receiveMessage.IndexPack, receiveMessage.AttachMessages));

                    MessageSendMsg messageSendMsg = receiveMessage as MessageSendMsg;
                    System.Threading.ThreadPool.QueueUserWorkItem(
                            new System.Threading.WaitCallback(this.FireMessageRcv),
                            messageSendMsg);

                    if (messageSendMsg.IsSendCheckOpt)
                    {
                        //回复确认收到消息
                        messageToSend = new MessageRecvMsg(MyInfo.Instance.UserName, MyInfo.Instance.HostName, MyInfo.Instance.IndexPackage, messageSendMsg.IndexPack);
                        this.SendMessage(messageToSend);
                    }
                }
                //消息已经被成功阅读
                else if (receiveMessage is MessageReadMsg)
                {
                    Log.Info(string.Format("发送给{0}({1})的{2}号消息已经被阅读.", this.hostName, this.IpEP.ToString(), receiveMessage.AttachMessages));
                }
                //消息已经被成功接受
                else if (receiveMessage is MessageRecvMsg)
                {
                    Log.Info(string.Format("发送给{0}({1})的{2}号消息已经被对方成功接受.", this.hostName, this.IpEP.ToString(), receiveMessage.AttachMessages));
                }
                //MessageGetDirFiles
                else if (receiveMessage is MessageGetDirFiles)
                {

                }
                //MessageGetFileData
                else if (receiveMessage is MessageGetFileData)
                {
                    //Log.Debug(string.Format("开始向{0}({1})发送文件{2}", this.hostName, this.IpEP.ToString(), this.fileToTrans.Path));
                    //FileStream f = this.fileToTrans.FileInfo.OpenRead();
                    //StateObject state = new StateObject();
                    //int len = 0;

                    //while ((len = f.Read(state.buffer, 0, StateObject.BufferSize)) != 0)
                    //{
                    //    base.TcpClient.Send(state.buffer, len, SocketFlags.None);
                    //    Array.Clear(state.buffer, 0, StateObject.BufferSize);
                    //}
                }
                //MessageReleaseFiles
                else if (receiveMessage is MessageReleaseFiles)
                {
                }
                else
                {
                    Log.Warning("暂时不支持此消息。");
                }
            }
            catch (NetExpection netEp)
            {
                Log.Error(netEp.Message);
            }
            catch (Exception ex)
            {
                Log.Error(ex.Message);
            }
        }

        //向当前用户发送MessageModel消息
        internal void SendMessage(MessageModel messageToSend)
        {
            byte[] bytesToSend = messageToSend.EncodingMessage();
            try
            {
                udpListner.BeginSendTo(
                    bytesToSend,
                    0,
                    bytesToSend.Length,
                    this.IpEP,
                    result =>
                    {
                        udpListner.EndSendTo(result);
                    },
                    null);
            }
            catch (Exception ex)
            {
                throw new NetExpection(string.Format("向{0}({1}发送消息失败。)", this.hostName, this.IpEP.ToString()), ex);
            }
        }

        /// <summary>
        /// 向当前用户发送纯文本消息
        /// </summary>
        /// <param name="txtMsg">要发送的文本消息</param>
        internal void SendTxtMsg(string txtMsg)
        {
            //构建消息
            MessageSendMsg messageToSend = new MessageSendMsg(
                                             MyInfo.Instance.UserName,
                                             MyInfo.Instance.HostName,
                                             MyInfo.Instance.IndexPackage,
                                             txtMsg,
                                             null,
                                             MyInfo.Instance.CheckOPT,
                                             MyInfo.Instance.SecretOPT);

            try
            {
                this.SendMessage(messageToSend);
            }
            catch (NetExpection netEP)
            {
                Log.Error(netEP.Message);
            }
            catch (Exception ex)
            {
                Log.Error(ex.Message);
            }
        }

        /// <summary>
        /// 向当前remoteuser发送文件或者文件夹
        /// </summary>
        /// <param name="filePath">文件或者文件夹路径</param>
        internal void SendFile(string filePath)
        {
            IPMsgFileInfo fileInfo = new IPMsgFileInfo(filePath);
            this.fileToTrans = fileInfo;
            //构建消息
            MessageSendMsg messageToSend = new MessageSendMsg(
                                             MyInfo.Instance.UserName,
                                             MyInfo.Instance.HostName,
                                             MyInfo.Instance.IndexPackage,
                                             null,
                                             fileInfo,
                                             MyInfo.Instance.CheckOPT,
                                             MyInfo.Instance.SecretOPT);

            try
            {
                this.SendMessage(messageToSend);
            }
            catch (NetExpection netEP)
            {
                Log.Error(netEP.Message);
            }
            catch (Exception ex)
            {
                Log.Error(ex.Message);
            }
        }

        /// <summary>
        /// 确认阅读消息，暂时未实现
        /// </summary>
        /// <param name="indexPack">包序号</param>
        internal void NotifyReadMsg(uint indexPack)
        {
            //构建消息
            MessageReadMsg messageToSend = new MessageReadMsg(
                                             MyInfo.Instance.UserName,
                                             MyInfo.Instance.HostName,
                                             MyInfo.Instance.IndexPackage,
                                             indexPack);

            try
            {
                this.SendMessage(messageToSend);
            }
            catch (NetExpection netEP)
            {
                Log.Error(netEP.Message);
            }
            catch (Exception ex)
            {
                Log.Error(ex.Message);
            }
        }

        private void FireUserExit(object obj)
        {
            RemoteUser remoteUser = obj as RemoteUser;
            EventPublicator.Instance.OnUserExitEvent(new UserEventArgs(remoteUser.IpEP.Address.ToString(), remoteUser.UserName, remoteUser.HostName));
        }

        private void FireMessageRcv(object obj)
        {
            MessageSendMsg messageSendMsg = obj as MessageSendMsg;
            EventPublicator.Instance.OnMessageRcvEvent(new MessageRcvArgs(this.hostName, messageSendMsg.AttachMessages));
        }
    }
}
